home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Disc to the Future 2
/
Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin
/
MAC
/
MPW_TOOL
/
TOOLS
/
TOOLS_WI
/
BYACC__
/
READER.C
< prev
next >
Wrap
C/C++ Source or Header
|
1989-11-19
|
25KB
|
1,297 lines
#include <stdio.h>
#include "defs.h"
#include "dep.h"
#include "files.h"
#include "gram.h"
#include "new.h"
#include "symtab.h"
#include "text.h"
#include "tokens.h"
extern int lineno;
extern YYSTYPE yylval;
extern char dflag;
extern char vflag;
typedef
struct rhs_cell
{
struct rhs_cell *next;
struct bucket *symbol;
}
rhs_cell;
typedef
struct rule_cell
{
struct rule_cell *next;
struct bucket *lhs;
struct rhs_cell *rhs;
short prec;
char assoc;
}
rule_cell;
LOCAL bucket *goal;
LOCAL bucket *augmenting_symbol;
LOCAL unsigned *numbers_used;
LOCAL text *stype;
LOCAL rule_cell *grammar;
LOCAL rule_cell *last_rule;
LOCAL rhs_cell *last_symbol;
LOCAL int rhslen;
LOCAL short prec;
LOCAL char assoc;
LOCAL char type_flag;
LOCAL bucket *lhs;
LOCAL int actname_count;
copy_section(fp)
register FILE *fp;
{
register int c;
c = getc(parser_file);
while (c != '@' && c != EOF)
{
putc(c, fp);
c = getc(parser_file);
if (c == '@')
{
c = getc(parser_file);
if (c != '@')
putc('@', fp);
}
}
}
declare(bp, tag, value, prec, assoc, class, used)
register bucket *bp;
char *tag;
short value;
short prec;
char assoc;
char class;
char used;
{
if (tag != NIL(char))
{
if (bp->tag != NIL(char) && bp->tag != tag)
retyped_warning(bp);
bp->tag = tag;
}
if (value != UNDEFINED)
{
if ( ! BIT(numbers_used, value))
{
SETBIT(numbers_used, value);
if (bp->value == UNDEFINED)
bp->value = value;
else if (bp->value != value)
revalued_warning(bp);
}
else if (bp->value != value)
value_error(value);
}
if (prec != 0)
{
if (bp->prec == 0)
bp->prec = prec;
else
reprec_warning(bp);
}
if (assoc != 0)
bp->assoc = assoc;
if (bp->class == UNKNOWN)
bp->class = class;
else if (class == TERMINAL)
{
if (bp->class == UNKNOWN)
bp->class = TERMINAL;
else if (class == NONTERMINAL)
terminal_start(bp);
}
if (used)
bp->used = 1;
}
int
declare_tokens(assoc, prec, used)
char assoc;
short prec;
char used;
{
register int tok;
register char *tag;
register int done;
register bucket *bp;
static char token_msg[] = "malformed %token declaration";
static char prec_msg[] = "malformed precedence decaration";
tag = NIL(char);
tok = yylex();
if (tok == TYPE_IDENTIFIER)
{
tag = yylval.bp->key;
tok = yylex();
}
done = 0;
while ( ! done)
{
if (tok != IDENTIFIER && tok != CHARACTER && tok != STRING)
{
if (assoc == TOKEN)
error(lineno, token_msg);
else
error(lineno, prec_msg);
}
while (tok == IDENTIFIER || tok == CHARACTER || tok == STRING)
{
bp = yylval.bp;
tok = yylex();
if (tok != NUMBER)
declare(bp, tag, UNDEFINED, prec, assoc, TERMINAL, used);
else
{
declare(bp, tag, yylval.i, prec, assoc, TERMINAL, used);
tok = yylex();
}
}
if (tok == COMMA)
tok = yylex();
else
done = 1;
}
return (tok);
}
int
declare_type()
{
register int tok;
register char *tag;
register int done;
static char malformed_msg[] = "malformed %type declaration";
tok = yylex();
if (tok != TYPE_IDENTIFIER)
error(lineno, malformed_msg);
tag = yylval.bp->key;
tok = yylex();
done = 0;
while ( ! done)
{
if (tok != IDENTIFIER && tok != CHARACTER && tok != STRING)
error(lineno, malformed_msg);
while (tok == IDENTIFIER || tok == CHARACTER || tok == STRING)
{
declare(yylval.bp, tag, UNDEFINED, 0, 0, UNKNOWN, 1);
tok = yylex();
}
if (tok == COMMA)
tok = yylex();
else
done = 1;
}
return (tok);
}
read_declarations()
{
register int tok;
register int prlevel;
static char no_grammar_msg[] = "grammar not found";
static char bad_start_msg[] = "malformed %start declaration";
static char reunion_msg[] = "multiple %union declarations";
static char malformed_msg[] = "malformed declaration";
prlevel = 0;
tok = yylex();
while(tok != MARK)
{
switch (tok)
{
case END_OF_FILE:
error(lineno, no_grammar_msg);
case TEXT:
write_text(yylval.tp, action_file);
free_text(yylval.tp);
tok = yylex();
break;
case TOKEN:
tok = declare_tokens(tok, 0, 1);
break;
case LEFT:
case RIGHT:
case NONASSOC:
prlevel++;
tok = declare_tokens(tok, prlevel, 0);
break;
case TYPE:
type_flag = 1;
tok = declare_type();
break;
case START:
tok = yylex();
if (tok != IDENTIFIER)
error(lineno, bad_start_msg);
goal = yylval.bp;
declare(yylval.bp, NIL(char), UNDEFINED, 0, 0, NONTERMINAL, 0);
tok = yylex();
break;
case UNION_TEXT:
if (stype != NIL(text))
error(lineno, reunion_msg);
stype = yylval.tp;
tok = yylex();
break;
default:
error(lineno, malformed_msg);
}
}
}
define_error_code()
{
if (first_symbol->value == UNDEFINED)
first_symbol->value = MAXCHAR + 1;
fprintf(action_file, "\n#define\tYYERRCODE\t%d\n", first_symbol->value);
}
define_stype()
{
if (stype != NIL(text))
write_text(stype, action_file);
else if (!type_flag)
{
fprintf(action_file, "\n#ifndef\tYYSTYPE\n");
fprintf(action_file, "typedef\tint\tYYSTYPE;\n");
fprintf(action_file, "#endif");
}
}
initialize_grammar()
{
register bucket *bp;
register rule_cell *rp;
register rhs_cell *rhsp;
bp = augmenting_symbol;
bp->class = NONTERMINAL;
bp->tag = goal->tag;
bp->value = 0;
bp->used = 1;
grammar = rp = NEW(rule_cell);
last_rule = rp;
rp->lhs = bp;
rp->rhs = rhsp = NEW(rhs_cell);
rhsp->symbol = goal;
nrules = 1;
nvars = 1;
assoc = 0;
prec = 0;
}
add_rule(bp)
register bucket *bp;
{
register rule_cell *rp;
static char lhs_msg[] = "a token appears on the lhs of a rule";
static char rule_msg[] = "too many rules";
static char symbol_msg[] = "too many symbols";
if (bp->class == UNKNOWN)
bp->class = NONTERMINAL;
else if (bp->class != NONTERMINAL)
error(lineno, lhs_msg);
if (bp->value == UNDEFINED)
{
if (nvars >= MAXSHORT) fatal(symbol_msg);
bp->value = nvars;
nvars++;
}
bp->used = 1;
if (nrules >= MAXSHORT) fatal(rule_msg);
nrules++;
last_rule->assoc = assoc;
last_rule->prec = prec;
lhs = bp;
last_rule->next = rp = NEW(rule_cell);
last_rule = rp;
rp->lhs = bp;
assoc = 0;
prec = 0;
rhslen = 0;
last_symbol = NIL(rhs_cell);
}
add_rhs(bp)
register bucket *bp;
{
register rhs_cell *rhsp;
rhslen++;
rhsp = NEW(rhs_cell);
if (last_symbol)
last_symbol->next = rhsp;
else
last_rule->rhs = rhsp;
last_symbol = rhsp;
rhsp->symbol = bp;
bp->used = 1;
if (bp->class == TERMINAL)
{
assoc = bp->assoc;
prec = bp->prec;
}
}
check_default_action()
{
if (type_flag && lhs->tag != NIL(char))
{
if (rhslen == 0)
no_rhs_warning();
else if (lhs->tag != last_rule->rhs->symbol->tag)
default_type_clash();
}
}
write_action(tp, bias, lhs_type)
text *tp;
int bias;
char *lhs_type;
{
register char *s, *end;
register int c;
register int k;
register char *local_type;
register rhs_cell *rhsp;
int m, n;
int negative;
int quote;
int inside;
fprintf(action_file, "\n\tcase %d:", nrules - 1);
fprintf(action_file, "\n#line %d \"%s\"\n", tp->start_line, input_file_name);
s = tp->ch;
end = s + tp->length;
while (s < end)
{
c = *s;
if (c == '$')
{
local_type = NIL(char);
n = 0;
negative = 0;
c = *++s;
if (c == '<')
{
c = *++s;
switch (c)
{
case 'A': case 'B': case 'C': case 'D': case 'E':
case 'F': case 'G': case 'H': case 'I': case 'J':
case 'K': case 'L': case 'M': case 'N': case 'O':
case 'P': case 'Q': case 'R': case 'S': case 'T':
case 'U': case 'V': case 'W': case 'X': case 'Y':
case 'Z':
case 'a': case 'b': case 'c': case 'd': case 'e':
case 'f': case 'g': case 'h': case 'i': case 'j':
case 'k': case 'l': case 'm': case 'n': case 'o':
case 'p': case 'q': case 'r': case 's': case 't':
case 'u': case 'v': case 'w': case 'x': case 'y':
case 'z':
case '_':
local_type = s;
n = 1;
c = *++s;
break;
default:
type_tag_error(tp, s);
}
while (c != '>')
{
switch (c)
{
case 'A': case 'B': case 'C': case 'D': case 'E':
case 'F': case 'G': case 'H': case 'I': case 'J':
case 'K': case 'L': case 'M': case 'N': case 'O':
case 'P': case 'Q': case 'R': case 'S': case 'T':
case 'U': case 'V': case 'W': case 'X': case 'Y':
case 'Z':
case 'a': case 'b': case 'c': case 'd': case 'e':
case 'f': case 'g': case 'h': case 'i': case 'j':
case 'k': case 'l': case 'm': case 'n': case 'o':
case 'p': case 'q': case 'r': case 's': case 't':
case 'u': case 'v': case 'w': case 'x': case 'y':
case 'z':
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
case '_':
n++;
c = *++s;
break;
default:
type_tag_error(tp, s);
}
}
c = *++s;
}
if (c == '$')
{
fprintf(action_file, "yyval");
if (local_type)
{
putc('.', action_file);
while (n > 0)
{
c = *local_type++;
putc(c, action_file);
n--;
}
}
else if (type_flag)
{
if (lhs_type == NIL(char))
lhs_type_error(tp, s);
fprintf(action_file, ".%s", lhs_type);
}
s++;
}
else
{
if (c == '-')
{
negative = 1;
c = *++s;
}
if ( ! IS_NUMERIC(c))
dollar_error(tp, s);
k = 0;
while (c == '0') c = *++s;
while (IS_NUMERIC(c))
{
k = 10*k + NUMERIC_VALUE(c);
c = *++s;
}
if (negative) k = -k;
fprintf(action_file, "yyvp[%d]", k - bias);
if (k > 0)
{
if (k > rhslen)
rhs_error(tp, s, k, rhslen);
else
{
rhsp = last_rule->rhs;
m = k;
while (m > 1)
{
rhsp = rhsp->next;
m--;
}
}
}
if (local_type)
{
putc('.', action_file);
while (n > 0)
{
c = *local_type++;
putc(c, action_file);
n--;
}
}
else if (type_flag)
{
if (k <= 0 || rhsp->symbol->tag == NIL(char))
rhs_type_error(tp, s, k);
fprintf(action_file, ".%s", rhsp->symbol->tag);
}
}
}
else if (c == QUOTE || c == DOUBLE_QUOTE)
{
quote = c;
putc(c, action_file);
c = *++s;
while (c != quote)
{
putc(c, action_file);
if (c == BACKSLASH)
{
c = *++s;
putc(c, action_file);
}
c = *++s;
}
putc(c, action_file);
s++;
}
else if (c == '/')
{
putc(c, action_file);
c = *++s;
if (c == '*')
{
putc(c, action_file);
c = *++s;
inside = 1;
while (inside)
{
while (c != '*')
{
putc(c, action_file);
c = *++s;
}
putc(c, action_file);
c = *++s;
if (c == '/') inside = 0;
}
putc(c, action_file);
s++;
}
}
else
{
putc(c, action_file);
s++;
}
}
fprintf(action_file, "\n\t\t\tbreak;\n");
}
mid_action(tp)
text *tp;
{
register rule_cell *rp;
register rhs_cell *rhsp;
register bucket *bp;
register int i;
register char *s;
char name[32];
static char symbol_msg[] = "too many symbols";
write_action(tp, rhslen + 1, NIL(char));
actname_count++;
sprintf(name, "$act%d", actname_count);
i = 0;
for (s = name; *s; s++) i++;
bp = make_bucket(IDENTIFIER, name, i);
bp->class = NONTERMINAL;
if (nvars >= MAXSHORT) fatal(symbol_msg);
bp->value = nvars;
nvars++;
bp->used = 1;
rhsp = NEW(rhs_cell);
rhsp->symbol = bp;
if (last_symbol)
last_symbol->next = rhsp;
else
last_rule->rhs = rhsp;
last_symbol = rhsp;
rhslen++;
rp = NEW(rule_cell);
rp->lhs = last_rule->lhs;
rp->rhs = last_rule->rhs;
last_rule->next = rp;
rp = last_rule;
last_rule = rp->next;
rp->lhs = bp;
rp->rhs = NIL(rhs_cell);
nrules++;
}
char *
skip_white_space2(s)
register char *s;
{
register int done, inside;
done = 0;
while (!done)
{
switch (*s)
{
case SP: case BS: case HT: case VT: case FF:
case CR: case NEWLINE: case DEL:
s++;
break;
case '/':
if (s[1] != '*')
done = 1;
else
{
s += 2;
inside = 1;
while (inside)
{
while (*s != '*') s++;
s++;
if (*s == '/')
{
s++;
inside = 0;
}
}
}
break;
default:
done = 1;
}
}
return (s);
}
int
is_default_action(tp)
register text *tp;
{
register char *s;
register int c;
register int result;
result = 0;
s = skip_white_space2(tp->ch);
c = *s++;
if (c == '{')
{
s = skip_white_space2(s);
c = *s++;
if (c == '$')
{
c = *s++;
if (c == '$')
{
s = skip_white_space2(s);
c = *s++;
if (c == '=')
{
s = skip_white_space2(s);
c = *s++;
if (c == '$')
{
c = *s++;
while (c == '0') c = *s++;
if (c == '1')
{
s = skip_white_space2(s);
c = *s++;
if (c == ';')
{
s = skip_white_space2(s);
c = *s;
if (c == '}')
result = 1;
}
}
}
}
}
}
else if (c == '}')
result = 1;
}
else if (c == '$')
{
c = *s++;
if (c == '$')
{
s = skip_white_space2(s);
c = *s++;
if (c == '=')
{
s = skip_white_space2(s);
c = *s++;
if (c == '$')
{
c = *s++;
while (c == '0') c = *s++;
if (c == '1')
{
s = skip_white_space2(s);
c = *s;
if (c == ';')
result = 1;
}
}
}
}
}
else if (c == ';')
result = 1;
return (result);
}
end_action(tp)
text *tp;
{
if (!is_default_action(tp))
{
write_action(tp, 1, last_rule->lhs->tag);
}
}
read_grammar()
{
register int tok;
register bucket *bp;
register text *tp;
static char rule_msg[] = "malformed rule";
static char prec_msg[] = "undefined precedence specifier";
tok = yylex();
while (tok == TEXT)
{
write_text(yylval.tp, action_file);
free_text(yylval.tp);
tok = yylex();
}
define_error_code();
define_stype();
copy_section(action_file);
if (tok != IDENTIFIER)
error(lineno, rule_msg);
if (goal == NIL(bucket))
goal = yylval.bp;
initialize_grammar();
add_rule(yylval.bp);
tok = yylex();
if (tok != COLON)
error(lineno, rule_msg);
tok = yylex();
while (tok != END_OF_FILE && tok != MARK)
{
switch (tok)
{
case IDENTIFIER:
bp = yylval.bp;
tok = yylex();
if (tok == COLON)
{
check_default_action();
add_rule(bp);
tok = yylex();
}
else
add_rhs(bp);
break;
case CHARACTER:
case STRING:
add_rhs(yylval.bp);
tok = yylex();
break;
case BAR:
check_default_action();
add_rule(lhs);
tok = yylex();
break;
case ACTION:
tp = yylval.tp;
tok = yylex();
switch (tok)
{
case END_OF_FILE:
end_action(tp);
break;
case IDENTIFIER:
bp = yylval.bp;
tok = yylex();
if (tok == COLON)
{
end_action(tp);
add_rule(bp);
tok = yylex();
}
else
{
mid_action(tp);
add_rhs(bp);
}
break;
case BAR:
end_action(tp);
add_rule(lhs);
tok = yylex();
break;
case SEMICOLON:
end_action(tp);
while (tok == SEMICOLON)
tok = yylex();
if (tok == IDENTIFIER)
{
add_rule(yylval.bp);
tok = yylex();
if (tok != COLON)
error(lineno, rule_msg);
tok = yylex();
}
break;
case CHARACTER:
case STRING:
case ACTION:
case PREC:
mid_action(tp);
break;
default:
error(lineno, rule_msg);
}
break;
case PREC:
tok = yylex();
if (tok != IDENTIFIER && tok != CHARACTER && tok != STRING)
error(lineno, rule_msg);
bp = yylval.bp;
if (bp->prec == 0)
error(lineno, prec_msg);
assoc = bp->assoc;
prec = bp->prec;
tok = yylex();
if (tok == ACTION)
{
end_action(yylval.tp);
tok = yylex();
}
while (tok == SEMICOLON)
tok = yylex();
if (tok == IDENTIFIER)
{
add_rule(yylval.bp);
tok = yylex();
if (tok != COLON)
error(lineno, rule_msg);
tok = yylex();
}
else if (tok == BAR)
{
add_rule(lhs);
tok = yylex();
}
break;
case SEMICOLON:
while (tok == SEMICOLON)
tok = yylex();
if (tok == IDENTIFIER)
{
add_rule(yylval.bp);
tok = yylex();
if (tok != COLON)
error(lineno, rule_msg);
tok = yylex();
}
break;
default:
error(lineno, rule_msg);
}
}
copy_section(action_file);
fprintf(action_file, "#line %d \"%s\"\n", lineno, input_file_name);
while ((tok = getc(input_file)) != EOF) putc(tok, action_file);
last_rule->assoc = assoc;
last_rule->prec = prec;
}
print_grammar()
{
register rule_cell *rp;
register rhs_cell *rhsp;
register int k, n;
register int spacing;
register bucket *lhs;
spacing = 0;
for (rp = grammar->next; rp; rp = rp->next)
{
k = rp->lhs->length;
if (k > spacing) spacing = k;
}
spacing++;
lhs = NIL(bucket);
k = 0;
for (rp = grammar->next; rp; rp = rp->next)
{
k++;
if (rp->lhs == lhs)
{
fprintf(verbose_file, "%4d\t", k);
for (n = spacing; n > 0; n--) putc(SP, verbose_file);
putc('|', verbose_file);
putc(SP, verbose_file);
}
else
{
lhs = rp->lhs;
fprintf(verbose_file, "\n%4d\t%s", k, lhs->key);
for (n = spacing - lhs->length; n > 0; n--) putc(SP, verbose_file);
putc(':', verbose_file);
putc(SP, verbose_file);
}
for (rhsp = rp->rhs; rhsp; rhsp = rhsp->next)
fprintf(verbose_file, " %s", rhsp->symbol->prname);
putc(NEWLINE, verbose_file);
}
if (k + 1 != nrules)
panic("print_grammar");
}
check_symbols()
{
register bucket *bp;
if ( ! goal->used)
no_goal(goal);
for (bp = first_symbol; bp; bp = bp->next)
{
if (bp->form == IDENTIFIER && bp->class == UNKNOWN)
{
undefined_warning(bp);
bp->class = TERMINAL;
}
}
}
number_symbols()
{
register bucket *bp;
register int number;
register int c;
static char token_msg[] = "too_many_tokens";
static char symbol_msg[] = "too_many_symbols";
number = MAXCHAR + 1;
nsyms = 1;
for (bp = first_symbol; bp; bp = bp->next)
{
if (bp->class == TERMINAL && bp->used)
{
bp->index = nsyms;
if (nsyms >= MAXSHORT) fatal(symbol_msg);
nsyms++;
if (bp->value == UNDEFINED)
{
if (bp->form == CHARACTER)
{
c = bp->key[0];
if (BIT(numbers_used, c))
revalued_warning(bp);
bp->value = c;
}
else
{
if (number >= MAX_TOKEN_NUMBER) fatal(token_msg);
number++;
while (BIT(numbers_used, number))
{
if (number >= MAX_TOKEN_NUMBER) fatal(token_msg);
number++;
}
bp->value = number;
}
}
}
}
ntokens = nsyms;
start_symbol = nsyms;
for (bp = first_symbol; bp; bp = bp->next)
{
if (bp->class == NONTERMINAL)
{
if (nsyms >= MAXSHORT) fatal(symbol_msg);
bp->index = bp->value + start_symbol;
nsyms++;
}
}
}
int
is_C_identifier(s, n)
register char *s;
int n;
{
register int i;
register int result;
result = 0;
if (n > 0)
{
switch (s[0])
{
case 'A': case 'B': case 'C': case 'D': case 'E':
case 'F': case 'G': case 'H': case 'I': case 'J':
case 'K': case 'L': case 'M': case 'N': case 'O':
case 'P': case 'Q': case 'R': case 'S': case 'T':
case 'U': case 'V': case 'W': case 'X': case 'Y':
case 'Z':
case 'a': case 'b': case 'c': case 'd': case 'e':
case 'f': case 'g': case 'h': case 'i': case 'j':
case 'k': case 'l': case 'm': case 'n': case 'o':
case 'p': case 'q': case 'r': case 's': case 't':
case 'u': case 'v': case 'w': case 'x': case 'y':
case 'z':
case '_':
result = 1;
}
}
for (i = 1; i < n && result; i++)
{
switch (s[i])
{
case 'A': case 'B': case 'C': case 'D': case 'E':
case 'F': case 'G': case 'H': case 'I': case 'J':
case 'K': case 'L': case 'M': case 'N': case 'O':
case 'P': case 'Q': case 'R': case 'S': case 'T':
case 'U': case 'V': case 'W': case 'X': case 'Y':
case 'Z':
case 'a': case 'b': case 'c': case 'd': case 'e':
case 'f': case 'g': case 'h': case 'i': case 'j':
case 'k': case 'l': case 'm': case 'n': case 'o':
case 'p': case 'q': case 'r': case 's': case 't':
case 'u': case 'v': case 'w': case 'x': case 'y':
case 'z':
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
case '_':
break;
default:
result = 0;
}
}
return(result);
}
define_symbols()
{
register bucket *bp;
register int c;
register int eq;
register int max;
max =0;
for (bp = first_symbol->next; bp; bp = bp->next)
{
if (bp->value > max) max = bp->value;
if (bp->class == TERMINAL && bp->form != CHARACTER)
{
if (bp->value != UNDEFINED && is_C_identifier(bp->key, bp->length))
{
fprintf(output_file, "\n#define\t%s\t%d", bp->key, bp->value);
if (dflag)
fprintf(temp_file, "\n#define\t%s\t%d", bp->key, bp->value);
}
}
}
fprintf(output_file, "\n#define\tYYMAXTOK\t%d\n", max);
if (!dflag) return;
fprintf(temp_file, "\n#define\tYYMAXTOK\t%d\n", max);
if (temp_file == defines_file)
fclose(temp_file);
else
{
fclose(temp_file);
temp_file = fopen(temp_file_name, "r");
if (temp_file == NULL) open_error(temp_file_name);
c = getc(defines_file);
eq = (c == getc(temp_file));
while (eq && c != EOF)
{
c = getc(defines_file);
eq = (c == getc(temp_file));
}
fclose(defines_file);
fclose(temp_file);
if ( ! eq)
{
defines_file = fopen(defines_file_name, "w");
if (defines_file == NULL) open_error(defines_file_name);
temp_file = fopen(temp_file_name, "r");
if (temp_file == NULL) open_error(temp_file_name);
c = getc(temp_file);
while (c != EOF)
{
putc(c, defines_file);
c = getc(temp_file);
}
}
}
defines_file = NIL(FILE);
temp_file = NIL(FILE);
}
pack_symbols()
{
register int n;
register bucket *bp;
symbol_name = NEW2(nsyms, char *);
symbol_value = NEW2(nsyms, short);
symbol_prec = NEW2(nsyms, short);
symbol_assoc = NEW2(nsyms, char);
symbol_name[0] = mk_prname(IDENTIFIER, "$eof", 4);
symbol_value[0] = 0;
symbol_name[start_symbol] = augmenting_symbol->prname;
symbol_value[start_symbol] = augmenting_symbol->value;
for (bp = first_symbol; bp; bp = bp->next)
{
n = bp->index;
if (n != 0)
{
symbol_name[n] = bp->prname;
symbol_value[n] = bp->value;
symbol_prec[n] = bp->prec;
symbol_assoc[n] = bp->assoc;
bp->key = NIL(char);
}
}
}
int
item_count()
{
register rule_cell *rp;
register rhs_cell *rhsp;
register int count;
count = 1;
for (rp = grammar; rp; rp = rp->next)
{
count++;
for (rhsp = rp->rhs; rhsp; rhsp = rhsp->next) count++;
}
return (count);
}
pack_grammar()
{
register rule_cell *rp;
register rhs_cell *rhsp;
register int m, n;
nitems = item_count();
if (nitems > MAXSHORT)
fatal("grammar too large");
ritem = NEW2(nitems, short);
rlhs = NEW2(nrules, short);
rrhs = NEW2(nrules + 1, short);
rprec = NEW2(nrules, short);
rassoc = NEW2(nrules, char);
m = 0;
n = 1;
for (rp = grammar; rp; rp = rp->next)
{
rlhs[m] = rp->lhs->index;
rrhs[m] = n;
rprec[m] = rp->prec;
rassoc[m] = rp->assoc;
for (rhsp = rp->rhs; rhsp; rhsp = rhsp->next)
{
ritem[n] = rhsp->symbol->index;
n++;
}
ritem[n] = -m;
n++;
m++;
}
rrhs[m] = n;
}
free_grammar()
{
register rule_cell *rp, *trp;
register rhs_cell *rhsp, *trhsp;
for (rp = grammar; rp; rp = trp)
{
for (rhsp = rp->rhs; rhsp; rhsp = trhsp)
{
trhsp = rhsp->next;
FREE(rhsp);
}
trp = rp->next;
FREE(rp);
}
}
reader()
{
numbers_used = NEW2(WORDSIZE(MAX_TOKEN_NUMBER + 1), unsigned);
stype = NIL(text);
augmenting_symbol = make_bucket(IDENTIFIER, "S'", 2);
FREE(augmenting_symbol->prname);
augmenting_symbol->prname = NEW2(3, char);
augmenting_symbol->prname[0] = 'S';
augmenting_symbol->prname[1] = QUOTE;
type_flag = 0;
actname_count = 0;
copy_section(output_file);
read_declarations();
read_grammar();
check_symbols();
number_symbols();
FREE(numbers_used);
define_symbols();
if (vflag) print_grammar();
pack_symbols();
pack_grammar();
free_symtab();
free_grammar();
}